/*
 * GameObject.cpp
 *
 *  Created on: 20.01.2012
 *      Author: Kirill Blinov
 *      Copyright: LGPL
 */

#include "GameObject.h"

void
GAME_OBJECT::Render( SHADER_COMMON_PARAMS &ShaderParams,
					 boost::function<void( RENDER_MODEL_INFO*,
										   IShaderProgram*,
	    		                           SHADER_COMMON_PARAMS& )> RenderOperator )
{
	for ( std::vector<SUBOBJECT_WITH_CONTROLLER*>::iterator it = models.begin(), end = models.end(); it != end; ++it )
	{
		SUBOBJECT_WITH_CONTROLLER *SubobjectWithController = *it;
		GAME_SUBOBJECT_INSTANCE   *Subobject = SubobjectWithController->GetSubobject();
		assert( Subobject );

		if ( Subobject->enabled )
		{
			ShaderParams.CameraDistance = distanceToCamera;
			ShaderParams.ModelMatrix = worldMatrix * Subobject->position * Subobject->correctionMatrix * correctionMatrix;
			if ( Subobject->textureDescriptors.size() > 0 )
			{
				//every texture descriptor of diffuse texture contains the name of common texture array object
				ShaderParams.DiffuseTexture = Subobject->textureDescriptors[0];
			}

			IShaderProgram* CurrentShaderProgram = Subobject->GetShaderProgram();
			assert( CurrentShaderProgram );

			RenderOperator( Subobject->renderInfo, Subobject->GetShaderProgram(), ShaderParams );

			//fprintf( stderr, "[ModelViewProjection] %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f\n",
        	//	ModelViewProjection[0].x , ModelViewProjection[0].y, ModelViewProjection[0].z, ModelViewProjection[0].w,
        	//	ModelViewProjection[1].x , ModelViewProjection[1].y, ModelViewProjection[1].z, ModelViewProjection[1].w,
        	//	ModelViewProjection[2].x , ModelViewProjection[2].y, ModelViewProjection[2].z, ModelViewProjection[2].w,
        	//	ModelViewProjection[3].x , ModelViewProjection[3].y, ModelViewProjection[3].z, ModelViewProjection[3].w);
		}
	}
}

glm::vec3
GAME_OBJECT::GetObjectCenterPosition( const bool InWorldSpace ) const
{
	glm::vec3 ObjectCenterPosition( correctionMatrix[3][0],
									correctionMatrix[3][1],
									correctionMatrix[3][2] );

	if ( InWorldSpace )
	{
		//ObjectCenterPosition *= worldMatrix;
	}

	return ObjectCenterPosition;
}

//---------------------------------------------------//

void
SUBOBJECT_WITH_CONTROLLER::SetSubobject( GAME_SUBOBJECT_INSTANCE* Subobject )
{
	if ( NULL != controller )
	{
		controller->SetGameObject( Subobject );
	}

	if ( subobject != NULL )
	{
		delete subobject;
	}
	subobject = Subobject;
}

void
SUBOBJECT_WITH_CONTROLLER::SetAnimationController( CAnimationController* AnimationController )
{
	if ( controller != NULL )
	{
		delete controller;
	}

	controller = AnimationController;
	controller->SetGameObject( subobject );
}
